#include "serverthread.h"
#include <QRegExp>

ServerThread::ServerThread(QObject *parent,int desc) :
    QThread(parent)
{
    TotalBytes = 0;
    fileNameSize = 0;
    bytesReceived = 0;
    mm = 0;
    isStop = true;

    fileSize = 0;
    receiveClass = 0;
    socket = new QTcpSocket();
    uartArduino = new uart();
    gcodes = new readGcode();

    int uart_fd = uartArduino->uartInit();
    uartListen = new QSocketNotifier(uart_fd,QSocketNotifier::Read, this); //listen the uart
    //    connect (uartListen, SIGNAL(activated(int)), this, SLOT(readArduino()));
    uartSocket = new QTcpSocket();
    uartSocket->setSocketDescriptor(uartListen->socket());
    connect(uartSocket,SIGNAL(readyRead()),this,SLOT(readArduino()));
    checkTimer = new QTimer();
   // connect(checkTimer,SIGNAL(timeout()),this,SLOT(readArduino()));

    socket->setSocketDescriptor(desc);
    connect(socket,SIGNAL(readyRead()),this,SLOT(ReceiveCmdFile()));

    connect(socket,SIGNAL(disconnected()),this,SLOT(clientDisconnect()));
}
ServerThread::~ServerThread()
{
    socket->close();
    uartSocket->close();
    qDebug()<<"Call the ~founction";

}
void ServerThread::clientDisconnect()
{

    qDebug()<<"Call the disconnect";
    this->quit();
    emit out();
}
//使用QSocketNotifier时，防止丢数据，需要注意
//1、Disable the notifier.
//2、Read data from the socket.
//3、Re-enable the notifier if you are interested in more data
void ServerThread::readArduino()
{
    uartListen->setEnabled(false);
    QByteArray ba = uartSocket->readAll();
    if(!ba.isEmpty())
    {
        QString le = ba;
        qDebug()<<le;
        QRegExp regOK(QString("ok"));
        QRegExp reg(QString("T: *([0-9]*\.[0-9]*)"));
        if(le.contains(reg))
        {
            int pos = le.indexOf(reg);
            pos = le.indexOf(reg);
            if(pos>=0)
            {
                //获取温度
                // float temperature = reg.cap(1).toFloat();
            }
        }
        if((!le.contains(reg))&&((le.contains(regOK))))
        {
            if(!isStop)
            {
                addToSender();
                sendCmdToArduino(tosend);
            }
        }
        else if(le.startsWith("start"))     //初始化开始
        {
            QString start = "CON";
            socket->write(start.toLatin1());
        }
        else
        {
            sendCmdToArduino(tosend);
        }

    }

    uartListen->setEnabled(true);
}
void ServerThread::addToSender()
{
    mutex.lock();

    while(1)
    {
        tosend = gcodes->readOneLine();
        if((tosend.startsWith(";")))
        {

        }
        else
        {
            break;
        }
    }
    mutex.unlock();
    if(tosend=="end")
    {
        cancleNow();
    }

}
void ServerThread::printNow()
{
    gcodes->setTargetFile("print.gcode");
    //get amount of command line
    // unsigned int po = gcodes->getTotalGcmd();
    checkTimer->start(15);
    addToSender();
    sendCmdToArduino("G28 \n");
    isStop = false;
}
void ServerThread::stopNow()
{
    isStop = true;
    checkTimer->stop();
}
void ServerThread::recoverNow()
{
    checkTimer->start(15);
    isStop = false;
    sendCmdToArduino(tosend);
}
void ServerThread::cancleNow()
{
    isStop = true;
    sendCmdToArduino("G28 \n");
    tosend = "";
    gcodes->reset();
    checkTimer->stop();
}

void ServerThread::ReceiveCmdFile()
{
    QDataStream in;
    in.setDevice(socket);
    in.setVersion(QDataStream::Qt_4_8); //设置流版本，以防数据格式错误

    if(bytesReceived<(sizeof(qint64)+sizeof(qint8)))
    {
        //获取数据包的长度和类型
        if(socket->bytesAvailable()>=(sizeof(qint64)+sizeof(qint8)))
        {
            in>>TotalBytes;
            in>>receiveClass;
            bytesReceived += (sizeof(qint64)+sizeof(qint8));
            if(receiveClass==20)
            {
                //删除目录下已经存在的所有gcode文件
                QFile::remove("./print.gcode");
                localFile = new QFile("print.gcode");
                if(!localFile->open(QFile::WriteOnly))
                {
                    return;
                }
                qDebug()<<"open successful   "<<receiveClass;
            }

        }
    }
    //如果 等于 10，则接收指令行
    if((bytesReceived>=(sizeof(qint64)+sizeof(qint8)))&&(receiveClass==10))
    {
        //直接将接受到的命令发送到下位机
        in>>command;
        QRegExp re("G1 E");
        bytesReceived += command.toLatin1().size();
        qDebug()<<"writed command:"<<command;
        if(command.contains(re))
        {
            sendCmdToArduino("M92 E100 \n");
            sendCmdToArduino("M91 \n");
            sendCmdToArduino(command);
            sendCmdToArduino("M90 \n");
            sendCmdToArduino("G92 E0 \n");
        }
        else
        {
            sendCmdToArduino("G91 \n");
            sendCmdToArduino(command);
            sendCmdToArduino("G90 \n");
        }
        if(command=="Stop")
        {
            stopNow();
        }
        else if(command=="Recover")
        {
            recoverNow();
        }
        else if(command=="Cancle")
        {
            cancleNow();
        }
        else if(command.startsWith("T"))
        {
            QRegExp re("T([0-9]*)");
            int pos = command.indexOf(re);

            if(pos>=0)
            {
                sendCmdToArduino(tr("M104 S%1").arg(re.cap(1)));
                qDebug()<<re.cap(1);
            }


        }
        command = "";

    }
    //如果 等于 20，则接收文件
    if((bytesReceived>=(sizeof(qint64)+sizeof(qint8)))&&(receiveClass==20))
    {
        if(bytesReceived<TotalBytes)
        {
            bytesReceived += socket->bytesAvailable();
            inBlock = socket->readAll();
            mm += localFile->write(inBlock);
            qDebug()<<tr("successed write=%1").arg(mm);
            inBlock.resize(0);
        }
    }
    qDebug()<<"received:"<<bytesReceived<<",total byte:"<<TotalBytes;

    //结束接收
    if((bytesReceived==TotalBytes)&&(TotalBytes!=0))
    {
        qDebug()<<tr("successed received!");
        bytesReceived = 0;
        TotalBytes = 0;
        mm = 0;

        if(receiveClass==20)
        {
            printNow();
            localFile->close();   //接收完文件后，一定要关闭，不然收到的文件会比原来的更小
            receiveClass=0;
        }
        else if(receiveClass==10)
        {
            command = "";
            receiveClass=0;
        }
    }

}
void ServerThread::sendCmdToArduino(QString command)
{

    //    char* po = command.toLatin1().data();
    mutex.lock();
    uartSocket->write(command.toLatin1());
    mutex.unlock();
    command = "";
}


//void ServerThread::connectPrinter(char* dev,char* file)
//{


//}
//void ServerThread::sendNow(QString cmd)
//{

//}
//void ServerThread::printNow()
//{

//}

//void ServerThread::pauseNow()
//{

//}
//void ServerThread::resumeNow()
//{

//}
//void ServerThread::disconnectNow()
//{

//}

